home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / r5update.zip / I18N_OUT.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  7KB  |  226 lines

  1. /*
  2.  * i18n_output.c
  3.  *
  4.  * Written by David Flanagan.  Copyright 1991, O'Reilly && Associates.
  5.  * This program is freely distributable without licensing fees and
  6.  * is provided without guarantee or warranty expressed or implied.
  7.  * This program is -not- in the public domain.
  8.  *
  9.  * This program demonstrates the use of some of the X11R5 internationalized
  10.  * text output functions.  To use it, set the LANG environment variable
  11.  * (if you are on a Unix system) to a desired locale, and invoke the
  12.  * program with a filename as the single command line argument.  The file
  13.  * should contain text in the encoding of the locale you set.  This
  14.  * program creates a very simple window and displays a single line of
  15.  * the file centered in the window.  Typing any key while the mouse
  16.  * is in the window will cause the next line of the file to be
  17.  * displayed, and clicking the mouse in the window will cause the program
  18.  * to exit.
  19.  *
  20.  * A good source of example text to use with this program is from the
  21.  * input methods contributed to X11R5.  Try the file:
  22.  *     contrib/im/Xsi/Wnn/manual/0/contents
  23.  * with locale ja_JP.ujis.  (If your version of Xlib uses the
  24.  * Ximp implementation of the X internationalization features, the
  25.  * locale name will probably be different.)
  26.  *
  27.  * This program has not been tested with the Ximp implementation.
  28.  */
  29.  
  30.  
  31. #include <stdio.h>
  32. #include <X11/Xlib.h>
  33. /*
  34.  * include <locale.h> or the non-standard X substitutes,
  35.  * depending on the X_LOCALE compilation flag
  36.  */        
  37. #include <X11/Xlocale.h>  
  38.  
  39.  
  40. /*
  41.  * This function draws a specified multi-byte string centered in
  42.  * a specified region of a window.  
  43.  */
  44. void DrawCenteredMbString(dpy, w, fontset, gc, str, num_bytes,x,y,width,height)
  45. Display *dpy;
  46. Window w;
  47. XFontSet fontset;
  48. GC gc;
  49. char *str;
  50. int num_bytes;
  51. int x, y, width, height;
  52. {
  53.     int escapement;
  54.     XRectangle boundingbox;
  55.     XRectangle dummy;
  56.     int originx, originy;
  57.  
  58.    /* 
  59.     * figure out how big the string will be.
  60.     * We should be able to pass NULL instead of &dummy, but
  61.     * XmbTextExtents is buggy in the Xsi implementation.
  62.     */
  63.     (void) XmbTextExtents(fontset, str, num_bytes,
  64.               &dummy, &boundingbox);
  65.  
  66.     /* XmbTextExtents should return the escapement, but it is buggy. */
  67.     /* Note that escapement is the same as boundingbox.width */
  68.     escapement = XmbTextEscapement(fontset, str, num_bytes);
  69.        
  70.    /*
  71.     * The string we want to center may be drawn left-to-right,
  72.     * right-to-left, or some of both, so computing the 
  73.     * drawing origin is a little tricky.  The bounding box's x
  74.     * and y coordinates are the upper left hand corner and are
  75.     * relative to the drawing origin.
  76.     * if boundingbox.x is 0, the the string is pure left-to-right.
  77.     * If it is equal to -boundingbox.width then the string is pure
  78.     * right-to-left, but it may not be either of these, so what
  79.     * we've got to do is choose the origin so that the bounding box
  80.     * is centered in the window without assuming that the orgin is
  81.     * at one end or another of the string:
  82.     *     originx + boundingbox.x = x + (width - escapement)/2
  83.     * and similarly for the baseline of the text:
  84.     *     originy + boundingbox.y = y + (height - boundingbox.height)/2
  85.     */
  86.     originx = x + (width - escapement)/2 - boundingbox.x;
  87.     originy = y + (height - boundingbox.height)/2 - boundingbox.y;
  88.  
  89.    /*
  90.     * now draw the string
  91.     */
  92.     XmbDrawImageString(dpy, w, fontset, gc, 
  93.                        originx, originy,
  94.                        str, num_bytes);
  95. }
  96.  
  97.  
  98.  
  99. main(argc, argv)
  100. int argc;
  101. char *argv[];
  102. {
  103.     Display *dpy;
  104.     int screen;
  105.     Window win;
  106.     GC gc;
  107.     XGCValues gcv;
  108.     XEvent event;
  109.     XFontSet fontset;
  110.     char *program_name = argv[0];
  111.     char **missing_charsets;
  112.     int num_missing_charsets = 0;
  113.     char *default_string;
  114.     int width = 0;
  115.     int height = 0;
  116.     FILE *f;
  117.     char linebuf[500];
  118.     int i;
  119.     
  120.     /*
  121.      * The error messages in this program are all in English.
  122.      * In a truely internationalized program, they would not
  123.      * be hardcoded; they would be looked up in a database of
  124.      * some sort.
  125.      */
  126.  
  127.     if (setlocale(LC_ALL, "") == NULL) {
  128.         (void) fprintf(stderr, "%s: cannot set locale.\n",program_name);
  129.         exit(1);
  130.     }
  131.  
  132.     if (argc != 2) {
  133.     (void) fprintf(stderr, "Usage: %s filename\n", argv[0]);
  134.     exit(1);
  135.     }
  136.  
  137.     if ((f = fopen(argv[1], "r")) == NULL) {
  138.     perror(argv[0]);
  139.     exit(1);
  140.     }
  141.     
  142.     if ((dpy = XOpenDisplay(NULL)) == NULL) {
  143.     (void) fprintf(stderr, "%s: cannot open Display.\n", program_name);
  144.     exit(1);
  145.     }
  146.  
  147.     if (!XSupportsLocale()) {
  148.         (void) fprintf(stderr, "%s: X does not support locale \"%s\".\n",
  149.                        program_name, setlocale(LC_ALL, NULL));
  150.         exit(1);
  151.     }
  152.  
  153.     if (XSetLocaleModifiers("") == NULL) {
  154.         (void) fprintf(stderr, "%s: Warning: cannot set locale modifiers.\n",
  155.                                 argv[0]);
  156.     }
  157.  
  158.     /*
  159.      * Create the fontset.
  160.      * Choose the fontlist carefully so as not to require font scaling.
  161.      */
  162.     fontset = XCreateFontSet(dpy,
  163.                  "-adobe-helvetica-*-r-*-*-*-120-*-*-*-*-*-*,\
  164.                               -misc-fixed-*-r-*-*-*-130-*-*-*-*-*-*",
  165.                  &missing_charsets, &num_missing_charsets,
  166.                  &default_string);
  167.     
  168.     /*
  169.      * if there are charsets for which no fonts can
  170.      * be found, print a warning message.  
  171.      */
  172.     if (num_missing_charsets > 0) {
  173.     (void)fprintf(stderr, "%s: The following charsets are missing:\n",
  174.               program_name);
  175.     for(i=0; i < num_missing_charsets; i++)
  176.         (void)fprintf(stderr, "%s: \t%s\n", program_name,
  177.               missing_charsets[i]);
  178.     XFreeStringList(missing_charsets);
  179.     
  180.     (void)fprintf(stderr, "%s: The string \"%s\" will be used in place\n",
  181.               program_name, default_string);
  182.     (void)fprintf(stderr, "%s: of any characters from those sets.\n",
  183.               program_name);
  184.     }
  185.  
  186.     screen = DefaultScreen(dpy);
  187.     win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 0, 0, 400, 100,
  188.                   2,WhitePixel(dpy,screen),BlackPixel(dpy,screen));
  189.     XSelectInput(dpy, win, ExposureMask | KeyPressMask |
  190.          ButtonPressMask | StructureNotifyMask);
  191.     XMapWindow(dpy,win);
  192.  
  193.     gc = XCreateGC(dpy,win,0,&gcv);
  194.     XSetForeground(dpy,gc,WhitePixel(dpy,screen));
  195.     XSetBackground(dpy,gc,BlackPixel(dpy,screen));
  196.  
  197.     if (fgets(linebuf, 500, f) == 0) exit(0);
  198.  
  199.     while(1) {
  200.         XNextEvent(dpy, &event);
  201.         switch (event.type) {
  202.         case Expose:
  203.             if (event.xexpose.count == 0)
  204.         DrawCenteredMbString(dpy, win, fontset, gc,
  205.                      linebuf, strlen(linebuf),
  206.                      0, 0, width, height);
  207.             break;
  208.     case ConfigureNotify:
  209.         width = event.xconfigure.width;
  210.         height = event.xconfigure.height;
  211.         break;
  212.         case KeyPress:
  213.         if (fgets(linebuf, 500, f) == 0) exit(0);
  214.         XClearWindow(dpy, win);
  215.         DrawCenteredMbString(dpy, win, fontset, gc,
  216.                  linebuf, strlen(linebuf),
  217.                  0, 0, width, height);
  218.         break;
  219.         case ButtonPress:
  220.             exit(0);
  221.         }
  222.     }
  223. }
  224.  
  225.  
  226.